#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <atomic>

using namespace std;
//
//namespace rtx
//{
//	template<class T>
//	class shared_ptr
//	{
//	public:
//		shared_ptr(T* ptr = nullptr)
//			: _ptr(ptr)
//			, _pCount(new int(1))
//			,_pMtx(new mutex)
//		{}
//
//		shared_ptr(const shared_ptr<T>& sp)
//			: _ptr(sp._ptr)
//			, _pCount(sp._pCount)
//			, _pMtx(sp._pMtx)
//		{
//			_pMtx->lock();
//			(*_pCount)++;
//			_pMtx->unlock();
//		}
//
//		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
//		{
//			//if (this != &sp)
//			if (_ptr != sp._ptr) // 防止自己给自己赋值,注意不能比较this,类似s1 = s2; 再来一次s1 = s2;
//			{                    // 比较_pCount也行
//				//if (--(*_pCount) == 0) // 防止产生内存泄漏,和析构一样,写成一个函数
//				//{
//				//	delete _ptr;
//				//	delete _pCount;
//				//}
//				Release();
//
//				_ptr = sp._ptr;
//				_pCount = sp._pCount;
//				_pMtx->lock();
//				(*_pCount)++;
//				_pMtx->unlock();
//			}
//			return *this;
//		}
//
//		void Release() // 防止产生内存泄漏,和析构一样,写成一个函数
//		{
//			bool flag = false;
//
//			_pMtx->lock();
//			if (--(*_pCount) == 0)
//			{
//				delete _ptr;
//				delete _pCount;
//
//				flag = true;
//			}
//			_pMtx->unlock();
//
//			if (flag)
//			{
//				delete _pMtx; // new出来的，引用计数为0时要delete
//			}
//		}
//		~shared_ptr()
//		{
//			Release();
//		}
//
//		T& operator*()
//		{
//			return *_ptr;
//		}
//		T* operator->()
//		{
//			return _ptr;
//		}
//		int use_count()
//		{
//			return *_pCount;
//		}
//	protected:
//		T* _ptr;
//		int* _pCount;// 引用计数,有多线程安全问题,学了linux再讲,不能用静态成员
//		mutex* _pMtx;
//	};
//}

//int main()
//{
//	rtx::shared_ptr<double> sp1(new double(7.77));
//	rtx::shared_ptr<double> sp2(sp1);
//
//	mutex mtx;
//
//	vector<thread> v(7);
//	int n = 100000;
//	for (auto& t : v)
//	{
//		t = thread([&](){
//			for (size_t i = 0; i < n; ++i)
//			{
//				// 拷贝是线程安全的
//				rtx::shared_ptr<double> sp(sp1);
//
//				// 访问资源不是
//				mtx.lock();
//				(*sp)++;
//				mtx.unlock();
//			}
//		});
//	}
//
//	for (auto& t : v)
//	{
//		t.join();
//	}
//	cout << *sp1 << endl;
//	cout << sp1.use_count() << endl;
//	return 0;
//}



//class Singleton
//{
//public:
//	static Singleton* GetInstance()
//	{
//		// 双检查加锁
//		if (m_pInstance == nullptr) // 保护第一次后，后续不需要加锁
//		{
//			unique_lock<mutex> lock(_mtx); // 加锁，防止new抛异常就用unique_lock
//			if (m_pInstance == nullptr) // 保护第一次时，线程安全
//			{
//				m_pInstance = new Singleton;
//			}
//		}
//
//		return m_pInstance;
//	}
//
//private:
//	Singleton() // 构造函数
//	{}
//	Singleton(const Singleton& s) = delete; // 禁止拷贝
//	Singleton& operator=(const Singleton& s) = delete; // 禁止赋值
//
//	// 静态单例对象指针
//	static Singleton* m_pInstance; // 单例对象指针
//	static mutex _mtx;
//};
//
//Singleton* Singleton::m_pInstance = nullptr; // 初始化为空
//mutex Singleton::_mtx;
//
//int main()
//{
//	Singleton* ps = Singleton::GetInstance();//获取单例对象
//
//	return 0;
//}


class Singleton
{
public:
	static Singleton* GetInstance()
	{
		// 局部的静态对象，第一次调用时初始化

		// 在C++11之前是不能保证线程安全的
		// C++11之前局部静态对象的构造函数调用初始化并不能保证线程安全的原子性。
		// C++11的时候修复了这个问题，所以这种写法，只能在支持C++11以后的编译器上使用
		static Singleton _s;
		return &_s;
	}

private:
	// 构造函数私有
	Singleton()
	{};

	Singleton(Singleton const&) = delete;
	Singleton& operator=(Singleton const&) = delete;
};

int main()
{
	Singleton::GetInstance();

	return 0;
}